package com.beta.auth.controller;

import com.alibaba.fastjson.JSON;
import com.beta.auth.config.UserAuthCfgBean;
import com.beta.auth.constants.BusinessConstants;
import com.beta.auth.constants.CacheConstans;
import com.beta.auth.dto.auth.GetUserInfoDto;
import com.beta.auth.dto.saas.SaasAuthDto;
import com.beta.auth.service.SelfAppAuthService;
import com.beta.auth.utils.HttpUtils;
import com.beta.auth.utils.ResponseUtils;
import com.beta.cat.service.RedissonService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Objects;

/**
 * <p>userCenter/userauth.controller.SaasAuthController</p>
 *
 * @description Saas 授权
 * @author: zdwang
 * @date 2021/11/30 18:33
 */
@Slf4j
@RestController
@RequestMapping("/connect/oauth2")
public class DeveloperAuthController {

    @Autowired
    private SelfAppAuthService commonService;

    @Autowired
    private UserAuthCfgBean userAuthCfgBean;

    @Autowired
    private RedissonService redissonService;

    /**
     * 获取重定向连接
     *
     * @param dto
     * @param request
     * @param resp
     */
    @RequestMapping("/authorize")
    public void authorize(SaasAuthDto dto, HttpServletRequest request, HttpServletResponse resp) {
        try {
            if (Objects.isNull(dto) || StringUtils.isBlank(dto.getState()) || StringUtils.isBlank(dto.getReturnUrl())) {
                ResponseUtils.toErrPage("请求参数错误", BusinessConstants.PARAMS_INVALID_CODE, resp);
            }
            // 以state为key缓存returnUrl 10s
            redissonService.set(dto.getState(), dto.getReturnUrl(), 10000);
            // 重定向
            String url = this.getAuthUrl(dto);
            log.info("SaasAuthController authorize url={}", url);
            ResponseUtils.sendRedirect(resp, userAuthCfgBean.getSafeHosts(), url);
        } catch (Exception e) {
            log.error("获取重定向连接异常：{}", e.getMessage(), e);
            ResponseUtils.toErrPage("系统异常", BusinessConstants.UNKNOWN_ERROR_CODE, resp);
        }
    }

    /**
     * 封装返回URL
     *
     * @param dto
     * @return
     * @throws UnsupportedEncodingException
     */
    public String getAuthUrl(SaasAuthDto dto) throws UnsupportedEncodingException {
        return new StringBuilder().append("https://open.weixin.qq.com/connect/oauth2/authorize?")
                .append("appid=").append(userAuthCfgBean.getCorpId())
                .append("&redirect_uri=").append(URLEncoder.encode(userAuthCfgBean.getDevelperRedirectUrl(), "UTF-8"))
                .append("&response_type=code")
                .append("&scope=snsapi_base")
                .append("&state=").append(dto.getState())
                .append("#wechat_redirect")
                .toString();
    }

    /**
     * 认证
     *
     * @param dto
     * @param resp
     */
    @RequestMapping("auth")
    public void secondAuth(SaasAuthDto dto, HttpServletResponse resp) throws Exception {
        if (Objects.isNull(dto) || StringUtils.isBlank(dto.getCode())) {
            ResponseUtils.toErrPage("请求参数错误", BusinessConstants.PARAMS_INVALID_CODE, resp);
        }
        // 调用微信API获取用户信息
        GetUserInfoDto userInfo = commonService.getUserInfo(dto.getCode(), false);
        if (Objects.isNull(userInfo)) {
            log.warn("获取到用户基本信息为null，dto = {}", JSON.toJSONString(dto));
            ResponseUtils.toErrPage(BusinessConstants.SYSTEM_ERROR_MSG, BusinessConstants.WX_ERROR_CODE, resp);
            return;
        }
        // 获取returnUrl
        String url = redissonService.get(dto.getState());

        StringBuilder redirectUrl = new StringBuilder();
        redirectUrl.append(url);
        // 判断returnUrl是否包含参数
        if (HttpUtils.hasParams(url).booleanValue()) {
            redirectUrl.append("&state=").append(dto.getState());
        } else {
            redirectUrl.append("?state=").append(dto.getState());
        }
        redirectUrl.append("&code=").append(dto.getCode());
        // 将userInfo存入redis
        String key = String.format(CacheConstans.SAAS_AUTH_USER_INFO, dto.getCode());
        redissonService.set(key, JSON.toJSONString(userInfo), 5000);
        // 重定向
        ResponseUtils.sendRedirect(resp, userAuthCfgBean.getSafeHosts(), redirectUrl.toString());
    }

}
